package tp.pr2;

import java.util.Scanner;

/**
 * Esta clase representa el motor del robot. Controla los movimientos del robot
 * procesando las instrucciones introducidas por el teclado. El motor se para
 * cuando el robot llega a un lugar con nave espacial o recibe la instruccion
 * Quit
 */
public class RobotEngine {
	private Place currentPlace;
	private Direction currentDirection = Direction.NORTH;
	private Street[] cityMap;
	private int fuel = 50;
	private int recycledMaterial = 0;

	/**
	 * Crea el motor del robot en un lugar inicial, orientado en una direccion
	 * inicial y con un mapa de la ciudad
	 */
	public RobotEngine(Place initialPlace, Direction direction, Street[] cityMap) {
		currentPlace = initialPlace;
		currentDirection = direction;
		this.cityMap = cityMap;
	}

	/**
	 * Se encarga de procesar una instruccion Move. En caso de exito (es posible
	 * moverse), actualiza currentPlace. Ademas, muestra mensajes por pantalla
	 * segun concluya la operacion
	 */
	public void move() {
		boolean success = false;

		// Rastrea el mapa de la ciudad hasta que encuentre un lugar alcanzable
		// en la direccion en la que se encuentre el robot orientado
		for(Street s : cityMap ) {
			if (s.comeOutFrom(currentPlace, currentDirection)) {
				success = true;
				currentPlace = s.nextPlace(currentPlace);
				break;
			}
		}

		if (success) {
			System.out.println(Message.MOVING.replace("<dir>",
					currentDirection.toString()));
			System.out.println(currentPlace.toString());
			System.out.println(Message.LOOKING.replace("<dir>",
					currentDirection.toString()));
		} else
			System.out.println(Message.NO_STREET.replace("<dir>",
					currentDirection.toString()));
	}

	/**
	 * Empieza el motor del robot
	 */
	public void startEngine() {
		Scanner sc = new Scanner(System.in);
		Interpreter interpreter = new Interpreter();
		Instruction instruction = new Instruction();

		System.out.println(currentPlace.toString());
		System.out.println(Message.LOOKING.replace("<dir>",
				currentDirection.toString()));

		// Bucle principal : mientras que la instruccion no sea Quit, o se
		// llegue a una nave espacial, solicita una nueva instruccion
		// al usuario y la procesa.
		while (instruction.getAction() != Action.QUIT
				&& !currentPlace.isSpaceship()) {
			System.out.println();
			System.out.print(Message.PROMPT);
			String line = sc.nextLine();
			instruction = interpreter.generateInstruction(line);

			if (instruction.isValid()) {
				switch (instruction.getAction()) {
				case HELP:
					System.out.println(interpreter.interpreterHelp());
					break;
				case TURN:
					if (instruction.getRotation() == Rotation.LEFT)
						currentDirection = currentDirection.rotateLeft();
					else if (instruction.getRotation() == Rotation.RIGHT)
						currentDirection = currentDirection.rotateLeft();
					System.out.println(Message.LOOKING.replace("<dir>",
							currentDirection.toString()));
					break;
				case MOVE:
					move();
					break;
				case QUIT:
					System.out.println(Message.COM_PROBLEMS);
					break;
				default:
					break;
				}
			} else
				System.out.println(Message.NOT_UNDERSTAND);

		}
		if (currentPlace.isSpaceship())
			System.out.println(Message.AT_SPACESHIP);
		sc.close();
	}
	
	public void addFuel(int inc){
		fuel += inc;
	}

	public int getFuel() {
		return fuel;
	}

	public int getRecycledMaterial() {
		return recycledMaterial;
	}
	
	public void addRecycledMaterial(int inc){
		recycledMaterial += inc;
	}
	
	public Street getHeadingStreet(){
		Street s = null;
		for (int i = 0; i < cityMap.length; i++){
			if (cityMap[i].comeOutFrom(currentPlace, currentDirection)){
				s = cityMap[i];
				break;
			}
		}
		return s;
	}
}
